#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using i128 = __int128;
const int N =  50000;

int fa[3 * N];  // a+n表示被a吃掉的一类，a+2n表示能吃a的一类

int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}

void merge(int x, int y) { fa[find(x)] = find(y); }

void solve() {
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= 3 * n; i++) fa[i] = i;
    int cnt = 0;
    for (int i = 1; i <= k; i++) {
        int d, x, y;
        cin >> d >> x >> y;
        if (x > n || y > n) {
            cnt++;
            continue;
        }
        else if (d == 1) {
            if (find(x) == find(y + n) || find(x) == find(y + 2 * n)) {
                cnt++;
                continue;
            } //x和y是同类  所以x和y必须在同层 否则就是假话
            merge(x, y);
            merge(x + n, y + n);
            merge(x + 2 * n, y + 2 * n);
        } else {
            if (find(x) == find(y) || find(x) == find(y + 2 * n)) {
                cnt++;
                continue;
            }  // x吃y 所以 x在第一层 y在第二层 或者 x在第二层 y在第三层
               // 或者x在第三城 y在第一层 否则是假话
            merge(x, y + n);
            merge(x + n, y + 2 * n);
            merge(x + 2 * n, y);
        }
    }
    cout << cnt << endl;
    return;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    solve();

    return 0;
}